From aaf087246484df8d659c8225f768d31264ccb3c8 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 8 Feb 2006 12:03:52 +0000 Subject: [PATCH] Use /dev/kmem to map dom0 xenstore page instead of abusing the foreign mapping interface. Change /proc/xen/xsd_mfn to /proc/xen/xsd_kva containing the kernel virtual address of the dom0 xenstore page. Update xenstored to use /proc/xen/xsd_kva. Signed-off-by: Keir Fraser Signed-off-by: Christian Limpach --- .../arch/i386/mm/ioremap-xen.c | 3 ++ .../drivers/xen/privcmd/privcmd.c | 7 ++- .../drivers/xen/xenbus/xenbus_probe.c | 44 +++++++++---------- tools/xenstore/xenstored_domain.c | 39 +++++++++++----- tools/xenstore/xenstored_proc.h | 2 +- 5 files changed, 59 insertions(+), 36 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c index f0a908a17f..a9a32ba8fb 100644 --- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c @@ -122,6 +122,9 @@ int direct_remap_pfn_range(struct vm_area_struct *vma, /* Same as remap_pfn_range(). */ vma->vm_flags |= VM_IO | VM_RESERVED; + if (domid == DOMID_SELF) + return -EINVAL; + return __direct_remap_pfn_range( vma->vm_mm, address, mfn, size, prot, domid); } diff --git a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c index 75ef91dedf..7758ca5cd9 100644 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c @@ -163,7 +163,12 @@ static int privcmd_ioctl(struct inode *inode, struct file *file, goto batch_err; } - vma = find_vma( current->mm, m.addr ); + if (m.dom == DOMID_SELF) { + ret = -EINVAL; + goto batch_err; + } + + vma = find_vma(current->mm, m.addr); if (!vma) { ret = -EINVAL; goto batch_err; diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c index 14af1a512f..cd4732c8fd 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @@ -863,16 +863,16 @@ EXPORT_SYMBOL(xenbus_resume); /* A flag to determine if xenstored is 'ready' (i.e. has started) */ -int xenstored_ready = 0; +int xenstored_ready = 0; int register_xenstore_notifier(struct notifier_block *nb) { int ret = 0; - if (xenstored_ready > 0) + if (xenstored_ready > 0) ret = nb->notifier_call(nb, 0, NULL); - else + else notifier_chain_register(&xenstore_chain, nb); return ret; @@ -889,7 +889,7 @@ EXPORT_SYMBOL(unregister_xenstore_notifier); void xenbus_probe(void *unused) { - BUG_ON((xenstored_ready <= 0)); + BUG_ON((xenstored_ready <= 0)); /* Enumerate devices in xenstore. */ xenbus_probe_devices(&xenbus_frontend); @@ -904,27 +904,27 @@ void xenbus_probe(void *unused) } -static struct proc_dir_entry *xsd_mfn_intf; +static struct proc_dir_entry *xsd_kva_intf; static struct proc_dir_entry *xsd_port_intf; -static int xsd_mfn_read(char *page, char **start, off_t off, +static int xsd_kva_read(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len; - len = sprintf(page, "%ld", xen_start_info->store_mfn); - *eof = 1; - return len; + int len; + len = sprintf(page, "0x%p", mfn_to_virt(xen_start_info->store_mfn)); + *eof = 1; + return len; } static int xsd_port_read(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len; + int len; - len = sprintf(page, "%d", xen_start_info->store_evtchn); - *eof = 1; - return len; + len = sprintf(page, "%d", xen_start_info->store_evtchn); + *eof = 1; + return len; } @@ -959,8 +959,8 @@ static int __init xenbus_probe_init(void) /* Allocate page. */ page = get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; + if (!page) + return -ENOMEM; /* We don't refcnt properly, so set reserved on page. * (this allocation is permanent) */ @@ -973,25 +973,25 @@ static int __init xenbus_probe_init(void) /* Next allocate a local port which xenstored can bind to */ op.cmd = EVTCHNOP_alloc_unbound; op.u.alloc_unbound.dom = DOMID_SELF; - op.u.alloc_unbound.remote_dom = 0; + op.u.alloc_unbound.remote_dom = 0; ret = HYPERVISOR_event_channel_op(&op); - BUG_ON(ret); + BUG_ON(ret); xen_start_info->store_evtchn = op.u.alloc_unbound.port; /* And finally publish the above info in /proc/xen */ - if((xsd_mfn_intf = create_xen_proc_entry("xsd_mfn", 0400))) - xsd_mfn_intf->read_proc = xsd_mfn_read; + if((xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0400))) + xsd_kva_intf->read_proc = xsd_kva_read; if((xsd_port_intf = create_xen_proc_entry("xsd_port", 0400))) xsd_port_intf->read_proc = xsd_port_read; } /* Initialize the interface to xenstore. */ - err = xs_init(); + err = xs_init(); if (err) { printk(KERN_WARNING "XENBUS: Error initializing xenstore comms: %i\n", err); - return err; + return err; } if (!dom0) { diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index fb73771787..563f07e596 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -27,6 +27,7 @@ #include #include #include +#include //#define DEBUG #include "utils.h" @@ -256,7 +257,7 @@ static char *talloc_domain_path(void *context, unsigned int domid) } static struct domain *new_domain(void *context, unsigned int domid, - unsigned long mfn, int port) + int port) { struct domain *domain; struct ioctl_evtchn_bind_interdomain bind; @@ -268,11 +269,6 @@ static struct domain *new_domain(void *context, unsigned int domid, domain->shutdown = 0; domain->domid = domid; domain->path = talloc_domain_path(domain, domid); - domain->interface = xc_map_foreign_range( - *xc_handle, domain->domid, - getpagesize(), PROT_READ|PROT_WRITE, mfn); - if (!domain->interface) - return NULL; list_add(&domain->list, &domains); talloc_set_destructor(domain, destroy_domain); @@ -290,7 +286,6 @@ static struct domain *new_domain(void *context, unsigned int domid, domain->conn->id = domid; domain->remote_port = port; - domain->mfn = mfn; return domain; } @@ -341,11 +336,19 @@ void do_introduce(struct connection *conn, struct buffered_data *in) if (domain == NULL) { /* Hang domain off "in" until we're finished. */ - domain = new_domain(in, domid, mfn, port); + domain = new_domain(in, domid, port); if (!domain) { send_error(conn, errno); return; } + domain->interface = xc_map_foreign_range( + *xc_handle, domid, + getpagesize(), PROT_READ|PROT_WRITE, mfn); + if (!domain->interface) { + send_error(conn, errno); + return; + } + domain->mfn = mfn; /* Now domain belongs to its connection. */ talloc_steal(domain->conn, domain); @@ -463,11 +466,11 @@ static int dom0_init(void) { int rc, fd; evtchn_port_t port; - unsigned long mfn; + unsigned long kva; char str[20]; struct domain *dom0; - fd = open(XENSTORED_PROC_MFN, O_RDONLY); + fd = open(XENSTORED_PROC_KVA, O_RDONLY); if (fd == -1) return -1; @@ -475,7 +478,7 @@ static int dom0_init(void) if (rc == -1) goto outfd; str[rc] = '\0'; - mfn = strtoul(str, NULL, 0); + kva = strtoul(str, NULL, 0); close(fd); @@ -491,7 +494,19 @@ static int dom0_init(void) close(fd); - dom0 = new_domain(NULL, 0, mfn, port); + dom0 = new_domain(NULL, 0, port); + + fd = open(_PATH_KMEM, O_RDWR); + if (fd == -1) + return -1; + + dom0->interface = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, + MAP_SHARED, fd, kva); + if (dom0->interface == MAP_FAILED) + goto outfd; + + close(fd); + talloc_steal(dom0->conn, dom0); evtchn_notify(dom0->port); diff --git a/tools/xenstore/xenstored_proc.h b/tools/xenstore/xenstored_proc.h index d065b05894..509ab658fd 100644 --- a/tools/xenstore/xenstored_proc.h +++ b/tools/xenstore/xenstored_proc.h @@ -20,7 +20,7 @@ #ifndef _XENSTORED_PROC_H #define _XENSTORED_PROC_H -#define XENSTORED_PROC_MFN "/proc/xen/xsd_mfn" +#define XENSTORED_PROC_KVA "/proc/xen/xsd_kva" #define XENSTORED_PROC_PORT "/proc/xen/xsd_port" -- 2.30.2